import random
import string
import time

from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import User
from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage
from django.shortcuts import render, redirect
from django.http import HttpResponse, JsonResponse
from django.urls import reverse
from commodity.models import CommodityInfos
from shopper.form import LoginForm, LoginModelForm
from shopper.models import OrderInfos, CartInfos
from shopper.pays import get_pay


# Create your views here.

def shopperView(request):
    """
    Django内置装饰器@login_required设置用户登录访问权限
    如果没登陆就跳转
    登录了才能正常打开
    """
    title = "个人中心"
    classContent = 'informations'
    #变量t，来自请求参数t，代表用户购买商品的支付时间
    t = request.GET.get('t','')
    p = request.GET.get('p',1)
    #获取payTime
    payTime = request.session.get('payTime','')
    if t and payTime and t==payTime:
        #当两者都不空且相等
        payInfo = request.session.get('payInfo','')
        OrderInfos.objects.create(**payInfo)
        # 在会话Session中删除该订单的支付时间和订单内容
        del request.session['payInfo']
        del request.session['payTime']
    #根据用户查询用户订单信息
    orderInfos = OrderInfos.objects.filter(user_id=request.user.id).order_by('-created')
    #分页
    paginator = Paginator(orderInfos, 7)
    try:
        pages = paginator.page(p)
    except PageNotAnInteger:
        pages = paginator.page(1)
    except EmptyPage:
        pages = paginator.page(paginator.num_pages)
    return render(request, 'shopper.html', locals())

def loginView(request):
    """
    用户登录视图函数，处理用户登录请求
    支持鲜有用户登录和新用户注册
    """
    # 定义变量title和classContent用于设置公用模板base.html的模板变量
    title = "用户登录"
    classContent = "logins"
    # 对用户的请求方式进行判断
    if request.method == "POST":
        # infos = LoginForm(data=request.POST)
        infos = LoginModelForm(data=request.POST)
        #if infos.is_valid():
        data = infos.data
        # 如果是POST请求，那么视图函数会执行注册和登录操作
        username = data['username']
        password = data['password']
        #查询是否存在
        if User.objects.filter(username=username):
            #验证账密
            user = authenticate(username=username, password=password)
            if user:
                login(request, user)
                return redirect(reverse('shopper:shopper'))
        else:
            #不存在，注册
            state = "注册成功"
            d = dict(username=username, password=password,is_staff=1,is_active=1)
            user = User.objects.create_user(**d)
            user.save()
        # else:
        #     #获取错误信息
        #     error_msg = infos.errors.as_json()
        #     print(error_msg)
    else:
        #处理HTTP的GET请求
        # infos = LoginForm()
        infos = LoginModelForm()
    return render(request, "login.html", locals())

def logoutView(request):
    # 调用Django的内置函数
    logout(request)
    # 页面重定向到首页
    return redirect(reverse('index:index'))
@login_required(login_url='/shopper/login.html')
def shopcartView(request):

    title = "我的购物车"
    classContent = "shopcarts"
    # 获取当前用户ID
    userId = request.user.id
    # 获取商品id
    id = request.GET.get('id', "")
    # 获取商品数量
    quantity = request.GET.get('quantity', 1)
    #判断id是否为空，，不为空说明当前请求中有参数id和quantity
    #需要进行操作
    if id:
        CartInfos.objects.update_or_create(
            commodityInfos__id=id,
            user_id=userId,
            defaults={'quantity': quantity}
        )
        return redirect('shopper:shopcart')
    #获取当前购物车的记录
    getUserId = CartInfos.objects.filter(user_id=userId)

    commodityDict = {x.commodityInfos_id : x.quantity for x in getUserId}
    commodityInfos = CommodityInfos.objects.filter(id__in=commodityDict.keys())

    return render(request, 'shopcart.html', locals())

def deleteAPI(request):
    #作为HTTP响应内容
    result = {'state':'success'}
    #获取用户ID
    userId = request.GET.get('userId', '')
    #获取商品ID
    commodityId = request.GET.get('commodityId', '')
    if userId:
        CartInfos.objects.filter(user_id=userId).delete()
    elif commodityId:
        CartInfos.objects.filter(commodityInfos__id=commodityId).delete()
    else:
        result= {'state': 'fail'}
    return JsonResponse(result)

def paysView(request):
    """
    支付宝视图函数，生成支付宝支付链接，处理支付前的订单信息准备
    """
    #从请求中获取参数total
    total = request.GET.get('total',0)
    #去掉货币符号
    total = total.replace('￥','')
    #金额格式验证
    try:
        #如果total为空或者零，说明当前购物车应付金额为零
        #或者HTTP请求没有设置请求参数，可以直接访问购物车页面
        total = float(total)
    except ValueError:
        return redirect('shopper:shopper')
    if total > 0:
        #用户正在结算操作
        #生成安全的订单编号
        timestamp = int(time.time()*1000)
        random_str = "".join(random.choices(string.digits, k=6))
        out_trade_no = f"{timestamp}{random_str}"
        #格式化金额为两位数的小数
        total_amount = "{0:.2f}".format(total)
        #准备订单信息，存入会话，支付成功后创建订单
        payInfo = dict(price=total,user_id=request.user.id,state="已支付")
        request.session['payInfo'] = payInfo
        request.session['payTime'] = out_trade_no
        domain = 'http://' + request.get_host()
        return_url = f"{domain}/shopper/pay_callback/"
        # 打印一些调试信息
        print(f"out_trade_no: {out_trade_no}, type: {type(out_trade_no)}")
        print(f"total_amount: {total_amount}, type: {type(total_amount)}")
        print(f"return_url: {return_url}, type: {type(return_url)}")
        #获取支付宝的支付链接
        url = get_pay(out_trade_no, total_amount, return_url)
        print("支付宝支付链接:", url)
        # 重定向到支付页面或者返回错误
        if url:
            return redirect(url)
        else:
            return redirect('shopper:shopcart')
    else:
        return redirect('shopper:shopcart')

def payCallbackView(request):
    """
    处理支付回调逻辑，可以做一些验证支付结果等操作
    """
    payTime = request.session.get('payTime','')
    if payTime:
        payInfo = request.session.get('payInfo', '')
        if payInfo:
            OrderInfos.objects.create(**payInfo)
            # 删除session中的数据
            del request.session['payInfo']
            del request.session['payTime']
            # 跳转到个人中心
    return redirect(reverse('shopper:shopper'))
